home *** CD-ROM | disk | FTP | other *** search
/ Oh!X 2000 Spring / Oh!X 2000 Spring Special CD-ROM (Japan) (Part 1).7z / Oh!X 2000 Spring Special CD-ROM (Japan) (Part 1).bin / MIPSSIM / asm.c < prev    next >
C/C++ Source or Header  |  1999-12-02  |  41KB  |  1,440 lines

  1. #include <stdio.h>
  2. #include "define.h"
  3. void asmips(char *base, FILE *fp);
  4.  
  5. #define MAXNAME 31
  6. #define MAXLABEL 10000
  7.  
  8. static ulong PC;
  9. static int   linenum;
  10.  
  11. static struct {
  12.   char  name[MAXNAME+1];
  13.   ulong addr;
  14. } label_table[MAXLABEL];
  15.  
  16. static int labelp = -1;
  17.  
  18. #define BC  0
  19. #define JMP 1
  20. #define LA  2
  21.  
  22. static struct {
  23.   char name[MAXNAME+1];
  24.   ulong idx;
  25.   int   typ;
  26. } unsolved[MAXLABEL];
  27.  
  28. static int unsolvedp = -1;
  29.  
  30. #define MAXLOCALF 16
  31. static ulong local_label[256];
  32. static int   for_llabel[256][MAXLOCALF];
  33. static int   typ_llabel[256][MAXLOCALF];
  34. static int   for_index[256];
  35.  
  36. static int search_label(char *);
  37. static int regist_label(char *, ulong); 
  38. static void regist_unsolv(char *, ulong, int);
  39.  
  40. typedef struct {
  41.   char    *nm;
  42.   void    (*type)(int);
  43.   ulong   code;
  44. } TABLE;
  45.  
  46. static void R_TYPE(int),I_TYPE(int),J_TYPE(int),C_TYPE(int),L_TYPE(int);
  47. static void Z_TYPE(int),X_TYPE(int),S_TYPE(int);
  48.  
  49. #define _CODE(OP,FN)    (ulong)((OP<<26)|FN)
  50.  
  51. static TABLE nmtab[]={
  52. /* MIPS-I */
  53.   "add",        R_TYPE,         _CODE(000,040),
  54.   "addi",       I_TYPE,         _CODE(010,0),
  55.   "addiu",      I_TYPE,         _CODE(011,0),
  56.   "addu",       R_TYPE,         _CODE(000,041),
  57.   "and",        R_TYPE,         _CODE(000,044),
  58.   "andi",       I_TYPE,         _CODE(014,0),
  59.   "bc0f",       I_TYPE,         _CODE(020,0)|(010<<21)|(000<<16),
  60.   "bc1f",       I_TYPE,         _CODE(021,0)|(010<<21)|(000<<16),
  61.   "bc2f",       I_TYPE,         _CODE(022,0)|(010<<21)|(000<<16),
  62.   "bc3f",       I_TYPE,         _CODE(023,0)|(010<<21)|(000<<16),
  63.   "bc0t",       I_TYPE,         _CODE(020,0)|(010<<21)|(001<<16),
  64.   "bc1t",       I_TYPE,         _CODE(021,0)|(010<<21)|(001<<16),
  65.   "bc2t",       I_TYPE,         _CODE(022,0)|(010<<21)|(001<<16),
  66.   "bc3t",       I_TYPE,         _CODE(023,0)|(010<<21)|(001<<16),
  67.   "beq",        I_TYPE,         _CODE(004,0),
  68.   "bgez",       I_TYPE,         _CODE(001,0)|(001<<16),
  69.   "bgezal",     I_TYPE,         _CODE(001,0)|(021<<16),
  70.   "bgtz",       I_TYPE,         _CODE(007,0),
  71.   "blez",       I_TYPE,         _CODE(006,0),
  72.   "bltz",       I_TYPE,         _CODE(001,0)|(000<<16),
  73.   "bltzal",     I_TYPE,         _CODE(001,0)|(020<<16),
  74.   "bne",        I_TYPE,         _CODE(005,0),
  75.   "break",      R_TYPE,         _CODE(000,015),
  76.   "cfc0",       R_TYPE,         _CODE(020,067)|(002<<21),
  77.   "cfc1",       R_TYPE,         _CODE(021,067)|(002<<21),
  78.   "cfc2",       R_TYPE,         _CODE(022,067)|(002<<21),
  79.   "cfc3",       R_TYPE,         _CODE(023,067)|(002<<21),
  80.   "ctc0",       R_TYPE,         _CODE(020,067)|(006<<21),
  81.   "ctc1",       R_TYPE,         _CODE(021,067)|(006<<21),
  82.   "ctc2",       R_TYPE,         _CODE(022,067)|(006<<21),
  83.   "ctc3",       R_TYPE,         _CODE(023,067)|(006<<21),
  84.   "div",        R_TYPE,         _CODE(000,032),
  85.   "divu",       R_TYPE,         _CODE(000,033),
  86.   "j",          J_TYPE,         _CODE(002,0),
  87.   "jal",        J_TYPE,         _CODE(003,0),
  88.   "jalr",       R_TYPE,         _CODE(000,011),
  89.   "jr",         R_TYPE,         _CODE(000,010),
  90.   "lb",         L_TYPE,         _CODE(040,0),
  91.   "lbu",        L_TYPE,         _CODE(044,0),
  92.   "lh",         L_TYPE,         _CODE(041,0),
  93.   "lhu",        L_TYPE,         _CODE(045,0),
  94.   "lui",        L_TYPE,         _CODE(017,0),
  95.   "lw",         L_TYPE,         _CODE(043,0),
  96.   "lwc0",       L_TYPE,         _CODE(060,0),
  97.   "lwc1",       L_TYPE,         _CODE(061,0),
  98.   "lwc2",       L_TYPE,         _CODE(062,0),
  99.   "lwc3",       L_TYPE,         _CODE(063,0),
  100.   "lwl",        L_TYPE,         _CODE(042,0),
  101.   "lwr",        L_TYPE,         _CODE(046,0),
  102.   "mfc0",       R_TYPE,         _CODE(020,067)|(000<<21),
  103.   "mfc1",       R_TYPE,         _CODE(021,067)|(000<<21),
  104.   "mfc2",       R_TYPE,         _CODE(022,067)|(000<<21),
  105.   "mfc3",       R_TYPE,         _CODE(023,067)|(000<<21),
  106.   "mfhi",       R_TYPE,         _CODE(000,020),
  107.   "mflo",       R_TYPE,         _CODE(000,022),
  108.   "mtc0",       R_TYPE,         _CODE(020,067)|(004<<21),
  109.   "mtc1",       R_TYPE,         _CODE(021,067)|(004<<21),
  110.   "mtc2",       R_TYPE,         _CODE(022,067)|(004<<21),
  111.   "mtc3",       R_TYPE,         _CODE(023,067)|(004<<21),
  112.   "mthi",       R_TYPE,         _CODE(000,021),
  113.   "mtlo",       R_TYPE,         _CODE(000,023),
  114.   "mult",       R_TYPE,         _CODE(000,030),
  115.   "multu",      R_TYPE,         _CODE(000,031),
  116.   "nor",        R_TYPE,         _CODE(000,047),
  117.   "or",         R_TYPE,         _CODE(000,045),
  118.   "ori",        I_TYPE,         _CODE(015,0),
  119.   "rfe",        C_TYPE,         _CODE(020,020)|(1<<25),
  120.   "sb",         L_TYPE,         _CODE(050,0),
  121.   "sh",         L_TYPE,         _CODE(051,0),
  122.   "sll",        R_TYPE,         _CODE(000,000),
  123.   "sllv",       R_TYPE,         _CODE(000,004),
  124.   "slt",        R_TYPE,         _CODE(000,052),
  125.   "slti",       I_TYPE,         _CODE(012,0),
  126.   "sltiu",      I_TYPE,         _CODE(013,0),
  127.   "sltu",       R_TYPE,         _CODE(000,053),
  128.   "sra",        R_TYPE,         _CODE(000,003),
  129.   "srav",       R_TYPE,         _CODE(000,007),
  130.   "srl",        R_TYPE,         _CODE(000,002),
  131.   "srlv",       R_TYPE,         _CODE(000,006),
  132.   "sub",        R_TYPE,         _CODE(000,042),
  133.   "subu",       R_TYPE,         _CODE(000,043),
  134.   "sw",         L_TYPE,         _CODE(053,0),
  135.   "swc0",       L_TYPE,         _CODE(070,0),
  136.   "swc1",       L_TYPE,         _CODE(071,0),
  137.   "swc2",       L_TYPE,         _CODE(072,0),
  138.   "swc3",       L_TYPE,         _CODE(073,0),
  139.   "swl",        L_TYPE,         _CODE(052,0),
  140.   "swr",        L_TYPE,         _CODE(056,0),
  141.   "syscall",    R_TYPE,         _CODE(000,014),
  142.   "tlbp",       C_TYPE,         _CODE(020,010)|(1<<25),
  143.   "tlbr",       C_TYPE,         _CODE(020,001)|(1<<25),
  144.   "tlbwi",      C_TYPE,         _CODE(020,002)|(1<<25),
  145.   "tlbwr",      C_TYPE,         _CODE(020,006)|(1<<25),
  146.   "xor",        R_TYPE,         _CODE(000,046),
  147.   "xori",       I_TYPE,         _CODE(016,0),
  148. /* MIPS-II */
  149.   "bc0fl",      I_TYPE,         _CODE(020,0)|(010<<21)|(002<<16),
  150.   "bc1fl",      I_TYPE,         _CODE(021,0)|(010<<21)|(002<<16),
  151.   "bc2fl",      I_TYPE,         _CODE(022,0)|(010<<21)|(002<<16),
  152.   "bc0tl",      I_TYPE,         _CODE(020,0)|(010<<21)|(003<<16),
  153.   "bc1tl",      I_TYPE,         _CODE(021,0)|(010<<21)|(003<<16),
  154.   "bc2tl",      I_TYPE,         _CODE(022,0)|(010<<21)|(003<<16),
  155.   "beql",       I_TYPE,         _CODE(024,0),
  156.   "bgezl",      I_TYPE,         _CODE(001,0)|(003<<16),
  157.   "bgezall",    I_TYPE,         _CODE(001,0)|(023<<16),
  158.   "bgtzl",      I_TYPE,         _CODE(027,0),
  159.   "blezl",      I_TYPE,         _CODE(026,0),
  160.   "bltzl",      I_TYPE,         _CODE(001,0)|(002<<16),
  161.   "bltzall",    I_TYPE,         _CODE(001,0)|(022<<16),
  162.   "bnel",       I_TYPE,         _CODE(025,0),
  163.   "tge",        R_TYPE,         _CODE(000,060),
  164.   "tgeu",       R_TYPE,         _CODE(000,061),
  165.   "tlt",        R_TYPE,         _CODE(000,062),
  166.   "tltu",       R_TYPE,         _CODE(000,063),
  167.   "teq",        R_TYPE,         _CODE(000,064),
  168.   "tne",        R_TYPE,         _CODE(000,066),
  169.   "tgei",       I_TYPE,         _CODE(001,0)|(010<<16),
  170.   "tgeiu",      I_TYPE,         _CODE(001,0)|(011<<16),
  171.   "tlti",       I_TYPE,         _CODE(001,0)|(012<<16),
  172.   "tltiu",      I_TYPE,         _CODE(001,0)|(013<<16),
  173.   "teqi",       I_TYPE,         _CODE(001,0)|(014<<16),
  174.   "tnei",       I_TYPE,         _CODE(001,0)|(016<<16),
  175.   "ll",         L_TYPE,         _CODE(060,0),
  176.   "sc",         L_TYPE,         _CODE(070,0),
  177.   "sync",       C_TYPE,         _CODE(000,017),
  178.   "eret",       C_TYPE,         _CODE(020,030)|(1<<25),
  179. /* MIPS-III */
  180.   "daddi",      I_TYPE,         _CODE(030,0),
  181.   "daddiu",     I_TYPE,         _CODE(031,0),
  182.   "ldl",        L_TYPE,         _CODE(032,0),
  183.   "ldr",        L_TYPE,         _CODE(033,0),
  184.   "sdl",        L_TYPE,         _CODE(054,0),
  185.   "sdr",        L_TYPE,         _CODE(055,0),
  186.   "lld",        L_TYPE,         _CODE(064,0),
  187.   "ldc1",       L_TYPE,         _CODE(065,0),
  188.   "ldc2",       L_TYPE,         _CODE(066,0),
  189.   "ld",         L_TYPE,         _CODE(067,0),
  190.   "lwu",        L_TYPE,         _CODE(047,0),
  191.   "scd",        L_TYPE,         _CODE(074,0),
  192.   "sdc1",       L_TYPE,         _CODE(075,0),
  193.   "sdc2",       L_TYPE,         _CODE(076,0),
  194.   "sd",         L_TYPE,         _CODE(077,0),
  195.   "dmfc0",      R_TYPE,         _CODE(020,067)|(001<<21),
  196.   "dmfc1",      R_TYPE,         _CODE(021,067)|(001<<21),
  197.   "dmfc2",      R_TYPE,         _CODE(022,067)|(001<<21),
  198.   "dmtc0",      R_TYPE,         _CODE(020,067)|(005<<21),
  199.   "dmtc1",      R_TYPE,         _CODE(021,067)|(005<<21),
  200.   "dmtc2",      R_TYPE,         _CODE(022,067)|(005<<21),
  201.   "dsll",       R_TYPE,         _CODE(000,070),
  202.   "dsllv",      R_TYPE,         _CODE(000,024),
  203.   "dsra",       R_TYPE,         _CODE(000,073),
  204.   "dsrav",      R_TYPE,         _CODE(000,027),
  205.   "dsrl",       R_TYPE,         _CODE(000,072),
  206.   "dsrlv",      R_TYPE,         _CODE(000,026),
  207.   "dsll32",     R_TYPE,         _CODE(000,074),
  208.   "dsrl32",     R_TYPE,         _CODE(000,076),
  209.   "dsra32",     R_TYPE,         _CODE(000,077),
  210.   "dmult",      R_TYPE,         _CODE(000,034),
  211.   "dmultu",     R_TYPE,         _CODE(000,035),
  212.   "ddiv",       R_TYPE,         _CODE(000,036),
  213.   "ddivu",      R_TYPE,         _CODE(000,037),
  214.   "dadd",       R_TYPE,         _CODE(000,054),
  215.   "daddu",      R_TYPE,         _CODE(000,055),
  216.   "dsub",       R_TYPE,         _CODE(000,056),
  217.   "dsubu",      R_TYPE,         _CODE(000,057),
  218. /* MIPS-IV */
  219.   "movf",       R_TYPE,         _CODE(000,001)|(000<<16),
  220.   "movt",       R_TYPE,         _CODE(000,001)|(001<<16),
  221.   "movz",       R_TYPE,         _CODE(000,012),
  222.   "movn",       R_TYPE,         _CODE(000,013),
  223.   "pref",       Z_TYPE,         _CODE(063,0),
  224.   "lwxc1",      X_TYPE,         _CODE(023,000),
  225.   "ldxc1",      X_TYPE,         _CODE(023,001),
  226.   "swxc1",      X_TYPE,         _CODE(023,010),
  227.   "sdxc1",      X_TYPE,         _CODE(023,011),
  228.   "prefx",      X_TYPE,         _CODE(023,017),
  229.   "madd.s",     X_TYPE,         _CODE(023,040),
  230.   "madd.d",     X_TYPE,         _CODE(023,041),
  231.   "msub.s",     X_TYPE,         _CODE(023,050),
  232.   "msub.d",     X_TYPE,         _CODE(023,051),
  233.   "nmadd.s",    X_TYPE,         _CODE(023,060),
  234.   "nmadd.d",    X_TYPE,         _CODE(023,061),
  235.   "nmsub.s",    X_TYPE,         _CODE(023,070),
  236.   "nmsub.d",    X_TYPE,         _CODE(023,071),
  237. /* ETC. */
  238.   "cache",      Z_TYPE,         _CODE(057,0),
  239.   "jalx",       J_TYPE,         _CODE(035,0),
  240. /* MIPS32 */
  241.   "madd",       S_TYPE,         _CODE(034,000),
  242.   "maddu",      S_TYPE,         _CODE(034,001),
  243.   "mul",        S_TYPE,         _CODE(034,002),
  244.   "msub",       S_TYPE,         _CODE(034,004),
  245.   "msubu",      S_TYPE,         _CODE(034,005),
  246.   "clz",        S_TYPE,         _CODE(034,040),
  247.   "clo",        S_TYPE,         _CODE(034,041),
  248.   "dclz",       S_TYPE,         _CODE(034,044),
  249.   "dclo",       S_TYPE,         _CODE(034,045),
  250.   "ssnop",      C_TYPE,         _CODE(034,077),
  251. /*END*/
  252. };
  253.  
  254. #define MAXTAB  (sizeof(nmtab)/sizeof(TABLE))
  255.  
  256. static char    *fnam[]={
  257. "add",  "sub",  "mul",  "div",  "sqrt",     "abs",  "mov",  "neg",
  258. "round.l","trunc.l","ceil.l","floor.l","round.w","trunc.w","ceil.w","floor.w",
  259. "",     "",     "",     "",     "",     "",     "",     "",
  260. "",     "",     "",     "",     "",     "",     "",     "",
  261. "cvt.s","cvt.d","",     "",     "cvt.w","cvt.l","",     "",
  262. "",     "",     "",     "",     "",     "",     "",     "",
  263. "c.f",  "c.un", "c.eq", "c.ueq","c.olt","c.ult","c.ole","c.ule",
  264. "c.sf", "c.ngle","c.seq","c.ngl","c.lt","c.nge","c.le", "c.ngt"
  265. };
  266.  
  267. #define MAXBUFF 1024
  268. static char Line[MAXBUFF];
  269. static char tmpBuf[MAXBUFF];
  270.  
  271. static char *linep;
  272.  
  273. long gen_val(char*);
  274. static long scan_val(char*, int);
  275.  
  276. static int regnum( char *reg)
  277. {
  278.   int     r;
  279.  
  280.   r= 0;
  281.   if(strcmp(reg,"r0")==0)  r=0;
  282.   if(strcmp(reg,"r1")==0)  r=1;
  283.   if(strcmp(reg,"r2")==0)  r=2;
  284.   if(strcmp(reg,"r3")==0)  r=3;
  285.   if(strcmp(reg,"r4")==0)  r=4;
  286.   if(strcmp(reg,"r5")==0)  r=5;
  287.   if(strcmp(reg,"r6")==0)  r=6;
  288.   if(strcmp(reg,"r7")==0)  r=7;
  289.   if(strcmp(reg,"r8")==0)  r=8;
  290.   if(strcmp(reg,"r9")==0)  r=9;
  291.   if(strcmp(reg,"r10")==0) r=10;
  292.   if(strcmp(reg,"r11")==0) r=11;
  293.   if(strcmp(reg,"r12")==0) r=12;
  294.   if(strcmp(reg,"r13")==0) r=13;
  295.   if(strcmp(reg,"r14")==0) r=14;
  296.   if(strcmp(reg,"r15")==0) r=15;
  297.   if(strcmp(reg,"r16")==0) r=16;
  298.   if(strcmp(reg,"r17")==0) r=17;
  299.   if(strcmp(reg,"r18")==0) r=18;
  300.   if(strcmp(reg,"r19")==0) r=19;
  301.   if(strcmp(reg,"r20")==0) r=20;
  302.   if(strcmp(reg,"r21")==0) r=21;
  303.   if(strcmp(reg,"r22")==0) r=22;
  304.   if(strcmp(reg,"r23")==0) r=23;
  305.   if(strcmp(reg,"r24")==0) r=24;
  306.   if(strcmp(reg,"r25")==0) r=25;
  307.   if(strcmp(reg,"r26")==0) r=26;
  308.   if(strcmp(reg,"r27")==0) r=27;
  309.   if(strcmp(reg,"r28")==0) r=28;
  310.   if(strcmp(reg,"r29")==0) r=29;
  311.   if(strcmp(reg,"r30")==0) r=30;
  312.   if(strcmp(reg,"r31")==0) r=31;
  313.   if(strcmp(reg,"zero")==0)r=0;
  314.   if(strcmp(reg,"at")==0)  r=1;
  315.   if(strcmp(reg,"v0")==0)  r=2;
  316.   if(strcmp(reg,"v1")==0)  r=3;
  317.   if(strcmp(reg,"a0")==0)  r=4;
  318.   if(strcmp(reg,"a1")==0)  r=5;
  319.   if(strcmp(reg,"a2")==0)  r=6;
  320.   if(strcmp(reg,"a3")==0)  r=7;
  321.   if(strcmp(reg,"t0")==0)  r=8;
  322.   if(strcmp(reg,"t1")==0)  r=9;
  323.   if(strcmp(reg,"t2")==0)  r=10;
  324.   if(strcmp(reg,"t3")==0)  r=11;
  325.   if(strcmp(reg,"t4")==0)  r=12;
  326.   if(strcmp(reg,"t5")==0)  r=13;
  327.   if(strcmp(reg,"t6")==0)  r=14;
  328.   if(strcmp(reg,"t7")==0)  r=15;
  329.   if(strcmp(reg,"s0")==0)  r=16;
  330.   if(strcmp(reg,"s1")==0)  r=17;
  331.   if(strcmp(reg,"s2")==0)  r=18;
  332.   if(strcmp(reg,"s3")==0)  r=19;
  333.   if(strcmp(reg,"s4")==0)  r=20;
  334.   if(strcmp(reg,"s5")==0)  r=21;
  335.   if(strcmp(reg,"s6")==0)  r=22;
  336.   if(strcmp(reg,"s7")==0)  r=23;
  337.   if(strcmp(reg,"t8")==0)  r=24;
  338.   if(strcmp(reg,"t9")==0)  r=25;
  339.   if(strcmp(reg,"k0")==0)  r=26;
  340.   if(strcmp(reg,"k1")==0)  r=27;
  341.   if(strcmp(reg,"gp")==0)  r=28;
  342.   if(strcmp(reg,"sp")==0)  r=29;
  343.   if(strcmp(reg,"s8")==0)  r=30;
  344.   if(strcmp(reg,"fp")==0)  r=30;
  345.   if(strcmp(reg,"ra")==0)  r=31;
  346.  
  347.   if(strcmp(reg,"lo")==0) r=32;
  348.   if(strcmp(reg,"hi")==0) r=33;
  349.  
  350.   if(strcmp(reg,"C0_Index"   )==0) r=0;
  351.   if(strcmp(reg,"C0_Random"  )==0) r=1;
  352.   if(strcmp(reg,"C0_EntryLo" )==0) r=2;
  353.   if(strcmp(reg,"C0_EntryLo0")==0) r=2;
  354.   if(strcmp(reg,"C0_EntryLo1")==0) r=3;
  355.   if(strcmp(reg,"C0_Context" )==0) r=4;
  356.   if(strcmp(reg,"C0_PageMask")==0) r=5;
  357.   if(strcmp(reg,"C0_Wired"   )==0) r=6;
  358.   if(strcmp(reg,"C0_Error"   )==0) r=7;
  359.   if(strcmp(reg,"C0_BadVAddr")==0) r=8;
  360.   if(strcmp(reg,"C0_Count"   )==0) r=9;
  361.   if(strcmp(reg,"C0_ASID"    )==0) r=10;
  362.   if(strcmp(reg,"C0_EntryHi" )==0) r=10;
  363.   if(strcmp(reg,"C0_Compare" )==0) r=11;
  364.   if(strcmp(reg,"C0_SR"      )==0) r=12;
  365.   if(strcmp(reg,"C0_Cause"   )==0) r=13;
  366.   if(strcmp(reg,"C0_EPC"     )==0) r=14;
  367.   if(strcmp(reg,"C0_PRId"    )==0) r=15;
  368.   if(strcmp(reg,"C0_Config"  )==0) r=16;
  369.   if(strcmp(reg,"C0_LLAddr"  )==0) r=17;
  370.   if(strcmp(reg,"C0_WatchLo" )==0) r=18;
  371.   if(strcmp(reg,"C0_WatchHi" )==0) r=19;
  372.   if(strcmp(reg,"C0_XContext")==0) r=20;
  373.   if(strcmp(reg,"C0_ECC"     )==0) r=26;
  374.   if(strcmp(reg,"C0_PErr"    )==0) r=26;
  375.   if(strcmp(reg,"C0_CacheErr")==0) r=27;
  376.   if(strcmp(reg,"C0_TagLo"   )==0) r=28;
  377.   if(strcmp(reg,"C0_TagHi"   )==0) r=29;
  378.   if(strcmp(reg,"C0_ErrorEPC")==0) r=30;
  379.  
  380.   if(strcmp(reg,"C1_SR"      )==0) r=31;
  381.  
  382.   if(strcmp(reg,"fp0")==0)  r=0x00;
  383.   if(strcmp(reg,"fp1")==0)  r=0x01;
  384.   if(strcmp(reg,"fp2")==0)  r=0x02;
  385.   if(strcmp(reg,"fp3")==0)  r=0x03;
  386.   if(strcmp(reg,"fp4")==0)  r=0x04;
  387.   if(strcmp(reg,"fp5")==0)  r=0x05;
  388.   if(strcmp(reg,"fp6")==0)  r=0x06;
  389.   if(strcmp(reg,"fp7")==0)  r=0x07;
  390.   if(strcmp(reg,"fp8")==0)  r=0x08;
  391.   if(strcmp(reg,"fp9")==0)  r=0x09;
  392.   if(strcmp(reg,"fp10")==0) r=0x0a;
  393.   if(strcmp(reg,"fp11")==0) r=0x0b;
  394.   if(strcmp(reg,"fp12")==0) r=0x0c;
  395.   if(strcmp(reg,"fp13")==0) r=0x0d;
  396.   if(strcmp(reg,"fp14")==0) r=0x0e;
  397.   if(strcmp(reg,"fp15")==0) r=0x0f;
  398.   if(strcmp(reg,"fp16")==0) r=0x10;
  399.   if(strcmp(reg,"fp17")==0) r=0x11;
  400.   if(strcmp(reg,"fp18")==0) r=0x12;
  401.   if(strcmp(reg,"fp19")==0) r=0x13;
  402.   if(strcmp(reg,"fp20")==0) r=0x14;
  403.   if(strcmp(reg,"fp21")==0) r=0x15;
  404.   if(strcmp(reg,"fp22")==0) r=0x16;
  405.   if(strcmp(reg,"fp23")==0) r=0x17;
  406.   if(strcmp(reg,"fp24")==0) r=0x18;
  407.   if(strcmp(reg,"fp25")==0) r=0x19;
  408.   if(strcmp(reg,"fp26")==0) r=0x1a;
  409.   if(strcmp(reg,"fp27")==0) r=0x1b;
  410.   if(strcmp(reg,"fp28")==0) r=0x1c;
  411.   if(strcmp(reg,"fp29")==0) r=0x1d;
  412.   if(strcmp(reg,"fp30")==0) r=0x1e;
  413.   if(strcmp(reg,"fp31")==0) r=0x1f;
  414.  
  415.   if(strcmp(reg,"pc")==0) r=0x1000;
  416.  
  417.   return r;
  418. }
  419.  
  420. static int search_label(char *nam)
  421. {
  422.   int i;
  423.  
  424.   for(i=0;i<=labelp;i++)
  425.     if(strcmp(label_table[i].name,nam)==0)
  426.       break;
  427.   if(i>labelp) return -1;/* not found */
  428.   return i;/* found */
  429. }
  430.  
  431. static int regist_label(char *nam, ulong pc)
  432. {
  433.   if(search_label(nam)>=0)
  434.     return -1;/* duplicated definition */
  435.   if((labelp+1)>=MAXLABEL)
  436.     return -2;/* table overflow */
  437.   ++labelp;
  438.   strncpy(label_table[labelp].name,nam,MAXNAME);
  439.   label_table[labelp].addr = pc;
  440.   return 0;
  441. }
  442.  
  443. static void regist_unsolv(char *nam, ulong pc, int typ)
  444. {
  445.   if((unsolvedp+1)>=MAXLABEL){
  446.     fprintf(stderr,"%d: too many unsolved labels!\n",linenum);
  447.     return;
  448.   }
  449.   unsolvedp++;
  450.   strncpy(unsolved[unsolvedp].name,nam,MAXNAME);
  451.   unsolved[unsolvedp].idx = pc;
  452.   unsolved[unsolvedp].typ = typ;
  453. }
  454.  
  455. static void add_label(ulong dst, ulong idx, int typ)
  456. {
  457.   ulong org;
  458.   ulong code;
  459.  
  460.   switch(typ){
  461.   case BC:
  462.     org   = idx;
  463.     code  = get_word(idx);
  464.     code |= ((((dst&0xffff)-(org&0xffff)-4)>>2)&0xffff);
  465.     put_word(idx,code);
  466.     break;
  467.   case JMP:
  468.     code  = get_word(idx);
  469.     code |= ((dst>>2)&0x3ffffff);
  470.     put_word(idx,code);
  471.     break;
  472.   case LA:
  473.     code  = get_word(idx);
  474.     code |= ((dst>>16)&0xffff);
  475.     put_word(idx,code);
  476.     code  = get_word(idx+4);
  477.     code |= ((dst    )&0xffff);
  478.     put_word(idx+4,code);
  479.     break;
  480.   }
  481. }
  482.  
  483. static void solve_label(void)
  484. {
  485.   int i;
  486.   int l;
  487.  
  488.   for(i=0;i<=unsolvedp;i++){
  489.     if((l=search_label(unsolved[i].name))<0){
  490.       fprintf(stderr,"unsolved label: %s\n",unsolved[i].name);
  491.     }
  492.     else{
  493.       add_label(label_table[l].addr,unsolved[i].idx,unsolved[i].typ);
  494.     }
  495.   }
  496. }
  497.  
  498. static void solve_local(int n)
  499. {
  500.   int i;
  501.  
  502.   for(i=0;i<=for_index[n];i++){
  503.     add_label(local_label[n],for_llabel[n][i],typ_llabel[n][i]);
  504.   }
  505.   for_index[n] = -1;
  506. }
  507.  
  508. static int white(int ch)
  509. {
  510.   return (ch==' ')||(ch=='\t');
  511. }
  512.  
  513. static int eol(int ch)
  514. {
  515.   return (ch=='\n')||(ch=='\0')||(ch=='\r');
  516. }
  517.  
  518. static int delim(int ch)
  519. {
  520.   return (ch==',')||white(ch)||(ch=='(')||(ch==')')||(ch==':');
  521. }
  522.  
  523. static void scan_sym(char *to)
  524. {
  525.   while(delim(*linep)) linep++;
  526.   while((!eol(*linep)) && (!delim(*linep))) *to++ = *linep++;
  527.   if(*linep==':'){
  528.     *to++ = ':';
  529.     linep++;
  530.   }
  531.   *to='\0';
  532. }
  533.  
  534. static int chk_num(int ch, int rad)
  535. {
  536.   ch &= 0xff;
  537.   if(rad<=10){
  538.     ch=ch-'0';
  539.     if((ch>=0)&&(ch<rad)) return ch;
  540.     else return -1;
  541.   }
  542.   if(rad==16){
  543.     if((ch>='0')&&(ch<='9')) return ch-'0';
  544.     if((ch>='a')&&(ch<='f')) return ch-'a'+10;
  545.     if((ch>='A')&&(ch<='F')) return ch-'A'+10;
  546.     return -1;
  547.   }
  548.   return -1;
  549. }
  550.  
  551. static char  last_ch;
  552. static ulong label_value;
  553.  
  554. static long scan_val(char *from, int radix)
  555. {
  556.   long num=0;
  557.   int  n;
  558.  
  559.   while(white(*from)) from++;
  560.   switch(radix){
  561.   case 2:
  562.   case 8:
  563.   case 10:
  564.   case 16:
  565.     while(*from){
  566.       if((n=chk_num(*from,radix))>=0)
  567.         num=num*radix+n;
  568.       else
  569.         break;
  570.       from++;
  571.     }
  572.     break;
  573.   default:
  574.     num=gen_val(from);
  575.   }
  576.   last_ch = *from;
  577.   return num;
  578. }
  579.  
  580. long gen_val(char *from)
  581. {
  582.   char  ch;
  583.   while(white(*from)) from++;
  584.   ch = *from++;
  585.   if(ch=='0'){
  586.     switch(*from){
  587.     case 'b': /* binary */
  588.     case 'B':
  589.       return scan_val(from+1,2);
  590.     case 'x': /* hexadecimal */
  591.     case 'X':
  592.       return scan_val(from+1,16);
  593.     default: /* octal */
  594.       return scan_val(from,8);
  595.     }
  596.   }
  597.   else if((ch>='0')&&(ch<='9')){
  598.     return scan_val(from-1,10);
  599.   }
  600.   else if(ch=='-'){
  601.     return (-1)*gen_val(from);
  602.   }
  603.   else{
  604.     return 0;
  605.   }
  606. }
  607.  
  608. #define LABEL  0
  609. #define LOCALF 1
  610. #define LOCALB 2
  611. #define ADDR   3
  612.  
  613. static int check_label(char *sym)
  614. {
  615.   if((*sym<'0')||(*sym>'9'))
  616.     return LABEL;
  617.   label_value = (ulong)gen_val(sym);
  618.   if(last_ch=='f')
  619.     return LOCALF;
  620.   if(last_ch=='b')
  621.     return LOCALB;
  622.   return ADDR;
  623. }
  624.  
  625. static int islocal(char *sym)
  626. {
  627.   int v=0;
  628.  
  629.   while(*sym){
  630.     if((*sym<'0')||(*sym>'9'))
  631.       break;
  632.     v = v*10+(*sym-'0');
  633.     sym++;
  634.   }
  635.   if(*sym=='\0')
  636.     return v;
  637.   return 0;
  638. }
  639.  
  640. static void S_TYPE(int insn)
  641. {
  642.   int fn;
  643.   int rs,rt,rd;
  644.  
  645.   switch((fn=nmtab[insn].code)&0x3f){
  646.   case 000:
  647.   case 001:
  648.   case 004:
  649.   case 005:
  650.     scan_sym(tmpBuf);
  651.     rs=regnum(tmpBuf);
  652.     scan_sym(tmpBuf);
  653.     rt=regnum(tmpBuf);
  654.     rd = 0;
  655.     break;
  656.   case 040:
  657.   case 041:
  658.   case 044:
  659.   case 045:
  660.     scan_sym(tmpBuf);
  661.     rt=regnum(tmpBuf);
  662.     scan_sym(tmpBuf);
  663.     rs=regnum(tmpBuf);
  664.     rd = rt;
  665.     break;
  666.   case 002:
  667.     scan_sym(tmpBuf);
  668.     rd=regnum(tmpBuf);
  669.     scan_sym(tmpBuf);
  670.     rs=regnum(tmpBuf);
  671.     scan_sym(tmpBuf);
  672.     rt=regnum(tmpBuf);
  673.     break;
  674.   }
  675.   fn |= ((rs&0x1f)<<21)|((rt&0x1f)<<16)|((rd&0x1f)<<11);
  676.   put_word(PC,fn);
  677. }
  678.  
  679. static void R_TYPE(int insn)
  680. {
  681.   int   fn;
  682.   int   rs,rt,rd,sa;
  683.  
  684.   switch((fn=nmtab[insn].code)&0x3f){
  685.   case 000: /* shift */
  686.   case 002:
  687.   case 003:
  688.   case 004:
  689.   case 006:
  690.   case 007:
  691.   case 024:
  692.   case 026:
  693.   case 027:
  694.   case 070:
  695.   case 072:
  696.   case 073:
  697.   case 074:
  698.   case 076:
  699.   case 077:
  700.     scan_sym(tmpBuf);
  701.     rd=regnum(tmpBuf);
  702.     scan_sym(tmpBuf);
  703.     rt=regnum(tmpBuf);
  704.     scan_sym(tmpBuf);
  705.     if(((fn&7)<4)||((fn&0x3f)>0x3b)){ /* immediate */
  706.       sa=gen_val(tmpBuf);
  707.       if(sa>31){
  708.     sa &= 0x1f;
  709.     fn &= 4;
  710.       }
  711.       else if(sa<0){
  712.     sa &= 0x1f;
  713.       }
  714.       rs=0;
  715.     }
  716.     else{ /* variable */
  717.       sa=0;
  718.       rs=regnum(tmpBuf);
  719.     }
  720.     break;
  721.   case 010: /* jr,jalr,sys,bp */
  722.   case 011:
  723.   case 014:
  724.   case 015:
  725.     if((fn&7)<4){ /* immediate */
  726.       scan_sym(tmpBuf);
  727.       rs=regnum(tmpBuf);
  728.       rt=rd=sa=0;
  729.       if(fn&1){ /* jalr */
  730.         int     temp;
  731.         scan_sym(tmpBuf);
  732.         rd=regnum(tmpBuf);
  733.         temp=rd;
  734.         rd=rs;
  735.         rs=temp;
  736.       }
  737.     }
  738.     else if((fn&7)==4){ /* Sys */
  739.       rs=rt=rd=sa=0;
  740.     }
  741.     else {
  742.       rs=rt=rd=sa=0;
  743.       scan_sym(tmpBuf);
  744.       if(tmpBuf[0]!=0){
  745.         sa=gen_val(tmpBuf);
  746.         rd=sa>>5;
  747.         rt=sa>>10;
  748.         rs=sa>>15;
  749.       }
  750.     }
  751.     break;
  752.   case 020: /* hi/lo */
  753.   case 021:
  754.   case 022:
  755.   case 023:
  756.     scan_sym(tmpBuf);
  757.     rd=regnum(tmpBuf);
  758.     if(fn&1){ /* to */
  759.       rs=rd;
  760.       rd=rt=sa=0;
  761.     }
  762.     else{ /* from */
  763.       rs=rt=sa=0;
  764.     }
  765.     break;
  766.   case 030: /* mul/div */
  767.   case 031:
  768.   case 032:
  769.   case 033:
  770.   case 034:
  771.   case 035:
  772.   case 036:
  773.   case 037:
  774.     rd=sa=0;
  775.     scan_sym(tmpBuf);
  776.     rs=regnum(tmpBuf);
  777.     scan_sym(tmpBuf);
  778.     rt=regnum(tmpBuf);
  779.     break;
  780.   case 040: /* 3-Op */
  781.   case 041:
  782.   case 042:
  783.   case 043:
  784.   case 044:
  785.   case 045:
  786.   case 046:
  787.   case 047:
  788.   case 052: /* slt,sltu */
  789.   case 053:
  790.   case 054:
  791.   case 055:
  792.   case 056:
  793.   case 057:
  794.   case 012:/* MOVZ */
  795.   case 013:/* MOVN */
  796.     sa=0;
  797.     scan_sym(tmpBuf);
  798.     rd=regnum(tmpBuf);
  799.     scan_sym(tmpBuf);
  800.     rs=regnum(tmpBuf);
  801.     scan_sym(tmpBuf);
  802.     rt=regnum(tmpBuf);
  803.     break;
  804.   case 001:/* MOVF/MOVT */
  805.     sa=0;
  806.     scan_sym(tmpBuf);
  807.     rd=regnum(tmpBuf);
  808.     scan_sym(tmpBuf);
  809.     rs=regnum(tmpBuf);
  810.     scan_sym(tmpBuf);
  811.     rt=(gen_val(tmpBuf)&0x7)<<2;
  812.     if(strcmp(tmpBuf,"cc0")==0) rt=(0<<2);
  813.     if(strcmp(tmpBuf,"cc1")==0) rt=(1<<2);
  814.     if(strcmp(tmpBuf,"cc2")==0) rt=(2<<2);
  815.     if(strcmp(tmpBuf,"cc3")==0) rt=(3<<2);
  816.     if(strcmp(tmpBuf,"cc4")==0) rt=(4<<2);
  817.     if(strcmp(tmpBuf,"cc5")==0) rt=(5<<2);
  818.     if(strcmp(tmpBuf,"cc6")==0) rt=(6<<2);
  819.     if(strcmp(tmpBuf,"cc7")==0) rt=(7<<2);
  820.     break;
  821.   case 060:/* trap */
  822.   case 061:
  823.   case 062:
  824.   case 063:
  825.   case 064:
  826.   case 066:
  827.     rd=sa=0;
  828.     scan_sym(tmpBuf);
  829.     rs=regnum(tmpBuf);
  830.     scan_sym(tmpBuf);
  831.     rt=regnum(tmpBuf);
  832.     scan_sym(tmpBuf);
  833.     if(tmpBuf[0]!='\0'){
  834.       rd = sa = gen_val(tmpBuf) & 0x3ff;
  835.       sa &=  0x1f;
  836.       rd >>= 5;
  837.     }
  838.     break;
  839.   case 067:/* COPz */
  840.   default:
  841.     rs=sa=0;
  842.     scan_sym(tmpBuf);
  843.     rt=regnum(tmpBuf);
  844.     scan_sym(tmpBuf);
  845.     rd=regnum(tmpBuf);
  846.     fn &= 0xffffffc0;
  847.   }
  848.   fn |= ((rs&0x1f)<<21)|((rt&0x1f)<<16)|((rd&0x1f)<<11)|((sa&0x1f)<<6);
  849.   put_word(PC,fn);
  850. }
  851.  
  852. static void I_TYPE(int insn)
  853. {
  854.   int   rs,rt;
  855.   long  imm;
  856.   int   cl;
  857.  
  858.   scan_sym(tmpBuf);
  859.   rt=regnum(tmpBuf);
  860.   switch(nmtab[insn].code){
  861.   case _CODE(001,0)|(000<<16):  /* BLTZ */
  862.   case _CODE(001,0)|(001<<16):  /* BGEZ */
  863.   case _CODE(001,0)|(002<<16):  /* BLTZL */
  864.   case _CODE(001,0)|(003<<16):  /* BFEZL */
  865.   case _CODE(001,0)|(020<<16):  /* BLTZAL */
  866.   case _CODE(001,0)|(021<<16):  /* BGEZAL */
  867.   case _CODE(001,0)|(022<<16):  /* BLTZALL */
  868.   case _CODE(001,0)|(023<<16):  /* BFEZALL */
  869.   case _CODE(006,0):      /* BLEZ  */
  870.   case _CODE(007,0):      /* BGTZ  */
  871.   case _CODE(026,0):      /* BLEZL */
  872.   case _CODE(027,0):      /* BGTZL */
  873.     rs=rt;
  874.     rt=(nmtab[insn].code&0x001f0000)>>16;
  875.     scan_sym(tmpBuf);
  876.     if((cl=check_label(tmpBuf))==ADDR){
  877.       imm = label_value;
  878.       imm = ((imm&0xffff)-(PC&0xffff)-4)>>2;
  879.     }
  880.     else if(cl==LOCALB){
  881.       imm = (long)local_label[label_value&0xff];
  882.       imm = ((imm&0xffff)-(PC&0xffff)-4)>>2;
  883.     }
  884.     else if(cl==LOCALF){
  885.       cl = (for_index[label_value&0xff]+1) % MAXLOCALF;
  886.       for_llabel[label_value&0xff][cl]=PC;
  887.       typ_llabel[label_value&0xff][cl]=BC;
  888.       for_index[label_value&0xff]=cl;
  889.       imm = 0;
  890.     }
  891.     else {
  892.       int i;
  893.       i = search_label(tmpBuf);
  894.       if(i<0){
  895.         regist_unsolv(tmpBuf,PC,BC);
  896.         imm = 0;
  897.       }
  898.       else {
  899.         imm = (long)label_table[i].addr;
  900.         imm = ((imm&0xffff)-(PC&0xffff)-4)>>2;
  901.       }
  902.     }
  903.     break;
  904.   case _CODE(004,0):      /* BEQ   */
  905.   case _CODE(005,0):      /* BNE   */
  906.   case _CODE(024,0):      /* BEQL  */
  907.   case _CODE(025,0):      /* BNEL  */
  908.     rs=rt;
  909.     scan_sym(tmpBuf);
  910.     rt=regnum(tmpBuf);
  911.     scan_sym(tmpBuf);
  912.     if((cl=check_label(tmpBuf))==ADDR){
  913.       imm = label_value;
  914.       imm = ((imm&0xffff)-(PC&0xffff)-4)>>2;
  915.     }
  916.     else if(cl==LOCALB){
  917.       imm = (long)local_label[label_value&0xff];
  918.       imm = ((imm&0xffff)-(PC&0xffff)-4)>>2;
  919.     }
  920.     else if(cl==LOCALF){
  921.       cl = (for_index[label_value&0xff]+1) % MAXLOCALF;
  922.       for_llabel[label_value&0xff][cl]=PC;
  923.       typ_llabel[label_value&0xff][cl]=BC;
  924.       for_index[label_value&0xff]=cl;
  925.       imm = 0;
  926.     }
  927.     else {
  928.       int i;
  929.       i = search_label(tmpBuf);
  930.       if(i<0){
  931.         regist_unsolv(tmpBuf,PC,BC);
  932.         imm = 0;
  933.       }
  934.       else {
  935.         imm = (long)label_table[i].addr;
  936.         imm = ((imm&0xffff)-(PC&0xffff)-4)>>2;
  937.       }
  938.     }
  939.     break;
  940.   case _CODE(020,0)|(010<<21)|(000<<16):/* BC0F */
  941.   case _CODE(021,0)|(010<<21)|(000<<16):/* BC1F */
  942.   case _CODE(022,0)|(010<<21)|(000<<16):/* BC2F */
  943.   case _CODE(023,0)|(010<<21)|(000<<16):/* BC3F */
  944.   case _CODE(020,0)|(010<<21)|(001<<16):/* BC0T */
  945.   case _CODE(021,0)|(010<<21)|(001<<16):/* BC1T */
  946.   case _CODE(022,0)|(010<<21)|(001<<16):/* BC2T */
  947.   case _CODE(023,0)|(010<<21)|(001<<16):/* BC3T */
  948.   case _CODE(020,0)|(010<<21)|(002<<16):/* BC0FL */
  949.   case _CODE(021,0)|(010<<21)|(002<<16):/* BC1FL */
  950.   case _CODE(022,0)|(010<<21)|(002<<16):/* BC2FL */
  951.   case _CODE(023,0)|(010<<21)|(002<<16):/* BC3FL */
  952.   case _CODE(020,0)|(010<<21)|(003<<16):/* BC0TL */
  953.   case _CODE(021,0)|(010<<21)|(003<<16):/* BC1TL */
  954.   case _CODE(022,0)|(010<<21)|(003<<16):/* BC2TL */
  955.   case _CODE(023,0)|(010<<21)|(003<<16):/* BC3TL */
  956.     rs=0;
  957.     rt= -1;
  958.     if(strcmp(tmpBuf,"cc0")==0) rt=(0<<2);
  959.     if(strcmp(tmpBuf,"cc1")==0) rt=(1<<2);
  960.     if(strcmp(tmpBuf,"cc2")==0) rt=(2<<2);
  961.     if(strcmp(tmpBuf,"cc3")==0) rt=(3<<2);
  962.     if(strcmp(tmpBuf,"cc4")==0) rt=(4<<2);
  963.     if(strcmp(tmpBuf,"cc5")==0) rt=(5<<2);
  964.     if(strcmp(tmpBuf,"cc6")==0) rt=(6<<2);
  965.     if(strcmp(tmpBuf,"cc7")==0) rt=(7<<2);
  966.     if(rt<0)
  967.       rt=0;
  968.     else
  969.       scan_sym(tmpBuf);
  970.     if((cl=check_label(tmpBuf))==ADDR){
  971.       imm = label_value;
  972.       imm = ((imm&0xffff)-(PC&0xffff)-4)>>2;
  973.     }
  974.     else if(cl==LOCALB){
  975.       imm = (long)local_label[label_value&0xff];
  976.       imm = ((imm&0xffff)-(PC&0xffff)-4)>>2;
  977.     }
  978.     else if(cl==LOCALF){
  979.       cl = (for_index[label_value&0xff]+1) % MAXLOCALF;
  980.       for_llabel[label_value&0xff][cl]=PC;
  981.       typ_llabel[label_value&0xff][cl]=BC;
  982.       for_index[label_value&0xff]=cl;
  983.       imm = 0;
  984.     }
  985.     else {
  986.       int i;
  987.       i = search_label(tmpBuf);
  988.       if(i<0){
  989.         regist_unsolv(tmpBuf,PC,BC);
  990.         imm = 0;
  991.       }
  992.       else {
  993.         imm = (long)label_table[i].addr;
  994.         imm = ((imm&0xffff)-(PC&0xffff)-4)>>2;
  995.       }
  996.     }
  997.     break;
  998.   case _CODE(001,0)|(010<<16): /* TGEI */
  999.   case _CODE(001,0)|(011<<16): /* TGEI */
  1000.   case _CODE(001,0)|(012<<16): /* TGEI */
  1001.   case _CODE(001,0)|(013<<16): /* TGEI */
  1002.   case _CODE(001,0)|(014<<16): /* TGEI */
  1003.   case _CODE(001,0)|(016<<16): /* TGEI */
  1004.     rs=rt;
  1005.     rt=0;
  1006.     scan_sym(tmpBuf);
  1007.     imm = gen_val(tmpBuf);
  1008.     break;
  1009.   default:
  1010.     scan_sym(tmpBuf);
  1011.     rs=regnum(tmpBuf);
  1012.     scan_sym(tmpBuf);
  1013.     imm = gen_val(tmpBuf);
  1014.   }
  1015.   put_word(PC,nmtab[insn].code|((rs&0x1f)<<21)|((rt&0x1f)<<16)|(imm&0xffff));
  1016. }
  1017.  
  1018. static void J_TYPE(int insn)
  1019. {
  1020.   ulong targ;
  1021.   int   cl;
  1022.  
  1023.   scan_sym(tmpBuf);
  1024.   if((cl=check_label(tmpBuf))==ADDR){
  1025.     targ = gen_val(tmpBuf);
  1026.     targ =(targ>>2)&0x3ffffff;
  1027.   }
  1028.   else if(cl==LOCALB){
  1029.     targ = local_label[label_value&0xff];
  1030.     targ =(targ>>2)&0x3ffffff;
  1031.   }
  1032.   else if(cl==LOCALF){
  1033.     cl = (for_index[label_value&0xff]+1) % MAXLOCALF;
  1034.     for_llabel[label_value&0xff][cl]=PC;
  1035.     typ_llabel[label_value&0xff][cl]=JMP;
  1036.     for_index[label_value&0xff]=cl;
  1037.     targ = 0;
  1038.   }
  1039.   else {
  1040.     int i;
  1041.     i = search_label(tmpBuf);
  1042.     if(i<0){
  1043.       regist_unsolv(tmpBuf,PC,JMP);
  1044.       targ = 0;
  1045.     }
  1046.     else {
  1047.       targ = label_table[i].addr;
  1048.       targ=(targ>>2)&0x3ffffff;
  1049.     }
  1050.   }
  1051.   put_word(PC,nmtab[insn].code|targ);
  1052. }
  1053.  
  1054. static void L_TYPE(int insn)
  1055. {
  1056.   long  offset;
  1057.   int   rt,base;
  1058.  
  1059.   scan_sym(tmpBuf);    /* rt */
  1060.   rt=regnum(tmpBuf);
  1061.   scan_sym(tmpBuf);    /* offset */
  1062.   offset= gen_val(tmpBuf);
  1063.   if(nmtab[insn].code==_CODE(017,0)){ /* lui */
  1064.     base=0;
  1065.   }
  1066.   else{
  1067.     scan_sym(tmpBuf);     /* base */
  1068.     base=regnum(tmpBuf);
  1069.   }
  1070.   put_word(PC,nmtab[insn].code|((base&0x1f)<<21)|((rt&0x1f)<<16)|(offset&0xffff));
  1071. }
  1072.  
  1073. static void C_TYPE(int insn)
  1074. {
  1075.   put_word(PC,nmtab[insn].code);
  1076. }
  1077.  
  1078. static void Z_TYPE(int insn)
  1079. {
  1080.   long  offset;
  1081.   int   rt,base;
  1082.  
  1083.   scan_sym(tmpBuf);    /* operation */
  1084.   rt=gen_val(tmpBuf)&0x1f;
  1085.   if(strcmp(tmpBuf,"Index_Inv_I"            )==0) rt=0x0;
  1086.   if(strcmp(tmpBuf,"Index_Writeback_Inv_D"  )==0) rt=0x1;
  1087.   if(strcmp(tmpBuf,"Index_Writeback_Inv_SD" )==0) rt=0x3;
  1088.   if(strcmp(tmpBuf,"Index_Load_Tag_I"       )==0) rt=0x4;
  1089.   if(strcmp(tmpBuf,"Index_Load_Tag_D"       )==0) rt=0x5;
  1090.   if(strcmp(tmpBuf,"Index_Load_Tag_SI"      )==0) rt=0x6;
  1091.   if(strcmp(tmpBuf,"Index_Load_Tag_SD"      )==0) rt=0x7;
  1092.   if(strcmp(tmpBuf,"Index_Store_Tag_I"      )==0) rt=0x8;
  1093.   if(strcmp(tmpBuf,"Index_Store_Tag_D"      )==0) rt=0x9;
  1094.   if(strcmp(tmpBuf,"Index_Store_Tag_SI"     )==0) rt=0xa;
  1095.   if(strcmp(tmpBuf,"Index_Store_Tag_SD"     )==0) rt=0xb;
  1096.   if(strcmp(tmpBuf,"Create_Dirty_D"         )==0) rt=0xd;
  1097.   if(strcmp(tmpBuf,"Create_Dirty_SD"        )==0) rt=0xf;
  1098.   if(strcmp(tmpBuf,"Hit_Inv_I"              )==0) rt=0x10;
  1099.   if(strcmp(tmpBuf,"Hit_Inv_D"              )==0) rt=0x11;
  1100.   if(strcmp(tmpBuf,"Hit_Inv_SI"             )==0) rt=0x12;
  1101.   if(strcmp(tmpBuf,"Hit_Inv_SD"             )==0) rt=0x13;
  1102.   if(strcmp(tmpBuf,"Hit_Writeback_Inv_D"    )==0) rt=0x15;
  1103.   if(strcmp(tmpBuf,"Fill_I"                 )==0) rt=0x14;
  1104.   if(strcmp(tmpBuf,"Hit_Writeback_D"        )==0) rt=0x19;
  1105.   if(strcmp(tmpBuf,"Hit_Writeback_SD"       )==0) rt=0x1b;
  1106.   if(strcmp(tmpBuf,"Hit_Writeback_I"        )==0) rt=0x18;
  1107.   if(strcmp(tmpBuf,"load"                   )==0) rt=0x00;
  1108.   if(strcmp(tmpBuf,"store"                  )==0) rt=0x01;
  1109.   if(strcmp(tmpBuf,"load_streamed"          )==0) rt=0x04;
  1110.   if(strcmp(tmpBuf,"store_streamed"         )==0) rt=0x05;
  1111.   if(strcmp(tmpBuf,"load_retained"          )==0) rt=0x06;
  1112.   if(strcmp(tmpBuf,"store_retained"         )==0) rt=0x07;
  1113.   if(strcmp(tmpBuf,"writeback_invalidate"   )==0) rt=0x19;
  1114.   scan_sym(tmpBuf);    /* offset */
  1115.   offset= gen_val(tmpBuf);
  1116.   scan_sym(tmpBuf);     /* base */
  1117.   base=regnum(tmpBuf);
  1118.   put_word(PC,nmtab[insn].code|((base&0x1f)<<21)|((rt&0x1f)<<16)|(offset&0xffff));
  1119. }
  1120.  
  1121. static void X_TYPE(int insn) /* COP1X */
  1122. {
  1123.   int fd,fr,fs,ft;
  1124.  
  1125.   scan_sym(tmpBuf);
  1126.   switch(nmtab[insn].code&0x3f){
  1127.   case 000:
  1128.   case 001:
  1129.   case 010:
  1130.   case 011:
  1131.     fs=regnum(tmpBuf);
  1132.     scan_sym(tmpBuf);
  1133.     ft=regnum(tmpBuf);
  1134.     scan_sym(tmpBuf);
  1135.     fr=regnum(tmpBuf);
  1136.     fd=0;
  1137.     break;
  1138.   case 040:
  1139.   case 041:
  1140.   case 050:
  1141.   case 051:
  1142.   case 060:
  1143.   case 061:
  1144.   case 070:
  1145.   case 071:
  1146.     fd=regnum(tmpBuf);
  1147.     scan_sym(tmpBuf);
  1148.     fr=regnum(tmpBuf);
  1149.     scan_sym(tmpBuf);
  1150.     fs=regnum(tmpBuf);
  1151.     scan_sym(tmpBuf);
  1152.     ft=regnum(tmpBuf);
  1153.     break;
  1154.   default:/* prefx */
  1155.     fd=0;
  1156.     fs=gen_val(tmpBuf)&0x1f;
  1157.     if(strcmp(tmpBuf,"load"                )==0) fs=0x00;
  1158.     if(strcmp(tmpBuf,"store"               )==0) fs=0x01;
  1159.     if(strcmp(tmpBuf,"load_streamed"       )==0) fs=0x04;
  1160.     if(strcmp(tmpBuf,"store_streamed"      )==0) fs=0x05;
  1161.     if(strcmp(tmpBuf,"load_retained"       )==0) fs=0x06;
  1162.     if(strcmp(tmpBuf,"store_retained"      )==0) fs=0x07;
  1163.     if(strcmp(tmpBuf,"writeback_invalidate")==0) fs=0x19;
  1164.     scan_sym(tmpBuf);
  1165.     ft=regnum(tmpBuf);
  1166.     scan_sym(tmpBuf);
  1167.     fr=regnum(tmpBuf);
  1168.   }
  1169.   put_word(PC,nmtab[insn].code|((fr&0x1f)<<21)|((ft&0x1f)<<16)|((fs&0x1f)<<11)|((fd&0x1f)<<6));
  1170. }
  1171.  
  1172. static long asmcp1(ulong, char*);
  1173.  
  1174. static ulong asmcpu(ulong pc, char *buf)
  1175. {
  1176.   int   i;
  1177.   long tmp;
  1178.   int   reg;
  1179.  
  1180.   for(i=0;i<MAXTAB;i++)
  1181.     if(strcmp(tmpBuf,nmtab[i].nm)==0) break;
  1182.   if(i>=MAXTAB){
  1183.     if(strcmp(tmpBuf,"nop")==0){
  1184.       put_word(PC,0);
  1185.       return PC+4;
  1186.     }
  1187.     if(strcmp(tmpBuf,".org")==0){
  1188.       scan_sym(tmpBuf);
  1189.       return (ulong)gen_val(tmpBuf);
  1190.     }
  1191.     if(strcmp(tmpBuf,".align")==0){
  1192.       scan_sym(tmpBuf);
  1193.       tmp = gen_val(tmpBuf);
  1194.       return PC+(tmp-(PC%tmp));
  1195.     }
  1196.     if(strcmp(tmpBuf,".word")==0){
  1197.       scan_sym(tmpBuf);
  1198.       while(tmpBuf[0]!='\0'){
  1199.     tmp = gen_val(tmpBuf);
  1200.     put_word(PC,tmp);
  1201.     PC += 4;
  1202.     scan_sym(tmpBuf);
  1203.       }
  1204.       return PC;
  1205.     }
  1206.     if(strcmp(tmpBuf,"move")==0){
  1207.       int reg2;
  1208.       scan_sym(tmpBuf);
  1209.       reg = regnum(tmpBuf)&0x1f;
  1210.       scan_sym(tmpBuf);
  1211.       reg2 = regnum(tmpBuf)&0x1f;
  1212.       put_word(PC,_CODE(000,045)|(reg2<<16)|(reg<<11));
  1213.       return PC+4;
  1214.     }
  1215.     if(strcmp(tmpBuf,"li")==0){
  1216.       scan_sym(tmpBuf);
  1217.       reg = regnum(tmpBuf)&0x1f;
  1218.       scan_sym(tmpBuf);
  1219.       tmp = gen_val(tmpBuf);
  1220.       if((tmp&0xffff0000)==0){
  1221.     put_word(PC,_CODE(015,0)|(reg<<16)|(tmp&0xffff));
  1222.     return PC+4;
  1223.       }
  1224.       if((tmp&0xffff)==0){
  1225.     put_word(PC,_CODE(017,0)|(reg<<16)|((tmp>>16)&0xffff));
  1226.     return PC+4;
  1227.       }
  1228.       if(tmp&0x8000){
  1229.     if((((tmp>>16)+1)&0xffff)==0){/* sign extended */
  1230.       put_word(PC,_CODE(011,0)|(reg<<16)|(tmp&0xffff));
  1231.       return PC+4;
  1232.     }
  1233.       }
  1234.       put_word(PC+0,_CODE(017,0)|(reg<<16)|((tmp>>16)&0xffff));
  1235.       put_word(PC+4,_CODE(015,0)|(reg<<21)|(reg<<16)|(tmp&0xffff));
  1236.       return PC+8;
  1237.     }
  1238.     if(strcmp(tmpBuf,"la")==0){
  1239.       int cl;
  1240.       scan_sym(tmpBuf);
  1241.       reg = regnum(tmpBuf)&0x1f;
  1242.       scan_sym(tmpBuf);
  1243.       if((cl=check_label(tmpBuf))==ADDR){
  1244.     tmp = gen_val(tmpBuf);
  1245.       }
  1246.       else if(cl==LOCALB){
  1247.     tmp = local_label[label_value&0xff];
  1248.       }
  1249.       else if(cl==LOCALF){
  1250.     cl = (for_index[label_value&0xff]+1) % MAXLOCALF;
  1251.     for_llabel[label_value&0xff][cl]=PC;
  1252.     typ_llabel[label_value&0xff][cl]=LA;
  1253.     for_index[label_value&0xff]=cl;
  1254.     tmp = 0;
  1255.       }
  1256.       else {
  1257.     int i;
  1258.     i = search_label(tmpBuf);
  1259.     if(i<0){
  1260.       regist_unsolv(tmpBuf,PC,LA);
  1261.       tmp = 0;
  1262.     }
  1263.     else {
  1264.       tmp = label_table[i].addr;
  1265.     }
  1266.       }
  1267.       put_word(PC+0,_CODE(017,0)|(reg<<16)|((tmp>>16)&0xffff));
  1268.       put_word(PC+4,_CODE(015,0)|(reg<<21)|(reg<<16)|(tmp&0xffff));
  1269.       return PC+8;
  1270.     }
  1271.     if(tmpBuf[0]==0)
  1272.       return pc;
  1273.     if(asmcp1(pc,tmpBuf)<0){
  1274.       fprintf(stderr,"%d: unknown nmemonic!\n",linenum);
  1275.       return pc;
  1276.     }
  1277.     else
  1278.       return pc+4;
  1279.   }
  1280.   (nmtab[i].type)(i);
  1281.   return pc+4;
  1282. }
  1283.  
  1284. static long asmcp1(ulong pc, char *buf)
  1285. {
  1286.   int     i;
  1287.   int     fmt;
  1288.   int     fd,fs,ft;
  1289.  
  1290.   i=strlen(buf);
  1291.   switch(buf[i-1]){
  1292.   case 's':
  1293.     fmt=000; break;
  1294.   case 'd':
  1295.     fmt=001; break;
  1296.   case 'w':
  1297.     fmt=004; break;
  1298.   case 'l':
  1299.     fmt=005; break;
  1300.   default:
  1301.     fprintf(stderr,"%d: illegal format:%c\n",linenum,buf[i-1]);
  1302.     return -1;
  1303.   }
  1304.   if(buf[i-2]!='.'){
  1305.     fprintf(stderr,"%d: unknown nmemonic(cp1):%s\n",linenum,buf);
  1306.     return -1;
  1307.   }
  1308.   buf[i-2]=0;
  1309.   for(i=0;i<=077;i++)
  1310.     if(strcmp(fnam[i],buf)==0) break;
  1311.   if(i>077){
  1312.     if(strcmp(buf,"movf")==0)  {i=021; ft=0;}
  1313.     else if(strcmp(buf,"movt")==0)  {i=021; ft=1;}
  1314.     else if(strcmp(buf,"movz")==0)  i=022;
  1315.     else if(strcmp(buf,"movn")==0)  i=023;
  1316.     else if(strcmp(buf,"recip")==0) i=025;
  1317.     else if(strcmp(buf,"rsqrt")==0) i=026;
  1318.     else{
  1319.       fprintf(stderr,"%d: unknown nmemonic(cp1):%s\n",linenum,buf);
  1320.       return -1;
  1321.     }
  1322.     switch(i){
  1323.     case 022:
  1324.     case 023:
  1325.       scan_sym(tmpBuf);
  1326.       fd=regnum(tmpBuf)&0x1f;
  1327.       scan_sym(tmpBuf);
  1328.       fs=regnum(tmpBuf)&0x1f;
  1329.       scan_sym(tmpBuf);
  1330.       ft=regnum(tmpBuf)&0x1f;
  1331.       break;
  1332.     case 026:
  1333.     case 027:
  1334.       scan_sym(tmpBuf);
  1335.       fd=regnum(tmpBuf)&0x1f;
  1336.       scan_sym(tmpBuf);
  1337.       fs=regnum(tmpBuf)&0x1f;
  1338.       ft=0;
  1339.       break;
  1340.     default:
  1341.       scan_sym(tmpBuf);
  1342.       fd=regnum(tmpBuf)&0x1f;
  1343.       scan_sym(tmpBuf);
  1344.       fs=regnum(tmpBuf)&0x1f;
  1345.       scan_sym(tmpBuf);
  1346.       ft|=(gen_val(tmpBuf)&0x7)<<2;
  1347.       if(strcmp(tmpBuf,"cc0")==0) ft|=(0<<2);
  1348.       if(strcmp(tmpBuf,"cc1")==0) ft|=(1<<2);
  1349.       if(strcmp(tmpBuf,"cc2")==0) ft|=(2<<2);
  1350.       if(strcmp(tmpBuf,"cc3")==0) ft|=(3<<2);
  1351.       if(strcmp(tmpBuf,"cc4")==0) ft|=(4<<2);
  1352.       if(strcmp(tmpBuf,"cc5")==0) ft|=(5<<2);
  1353.       if(strcmp(tmpBuf,"cc6")==0) ft|=(6<<2);
  1354.       if(strcmp(tmpBuf,"cc7")==0) ft|=(7<<2);
  1355.     }
  1356.   }
  1357.   else{ /* MIPS-I/II/III */
  1358.     scan_sym(tmpBuf);
  1359.     if(i>=060){ /* compare */
  1360.       fd= -1;
  1361.       if(strcmp(tmpBuf,"cc0")==0) fd=(0<<2);
  1362.       if(strcmp(tmpBuf,"cc1")==0) fd=(1<<2);
  1363.       if(strcmp(tmpBuf,"cc2")==0) fd=(2<<2);
  1364.       if(strcmp(tmpBuf,"cc3")==0) fd=(3<<2);
  1365.       if(strcmp(tmpBuf,"cc4")==0) fd=(4<<2);
  1366.       if(strcmp(tmpBuf,"cc5")==0) fd=(5<<2);
  1367.       if(strcmp(tmpBuf,"cc6")==0) fd=(6<<2);
  1368.       if(strcmp(tmpBuf,"cc7")==0) fd=(7<<2);
  1369.       if(fd<0) /* no cc */
  1370.     fd=0;
  1371.       else
  1372.     scan_sym(tmpBuf);
  1373.       fs=regnum(tmpBuf)&0x1f;
  1374.       scan_sym(tmpBuf);
  1375.       ft=regnum(tmpBuf);
  1376.     }
  1377.     else{
  1378.       fd=regnum(tmpBuf)&0x1f;
  1379.       scan_sym(tmpBuf);
  1380.       fs=regnum(tmpBuf)&0x1f;
  1381.       if(i<4){
  1382.     scan_sym(tmpBuf);
  1383.     ft=regnum(tmpBuf)&0x1f;
  1384.       }
  1385.       else
  1386.     ft=0;
  1387.     }
  1388.   }
  1389.   put_word(pc,(021<<26)|(1<<25)|(fmt<<21)|(ft<<16)|(fs<<11)|(fd<<6)|i);
  1390.   return 0;
  1391. }
  1392.  
  1393. #define LittleEndian 0
  1394. #define BigEndian    1
  1395.  
  1396. static int endian = LittleEndian;
  1397.  
  1398. void asmips(char *base, FILE *fp)
  1399. {
  1400.   int  i;
  1401.  
  1402.   linenum = 0;
  1403.   labelp = -1;
  1404.   unsolvedp = -1;
  1405.   for(i=1;i<256;i++)
  1406.     for_index[i] = -1;
  1407.   if(*base!='\0')
  1408.     PC = (ulong)gen_val(base);
  1409.   printf("%08x ",PC);fflush(stdout);
  1410.   while(fgets(Line,MAXBUFF,fp)!=NULL){
  1411.     linep = Line;
  1412.     linenum++;
  1413.     scan_sym(tmpBuf);
  1414.     if(tmpBuf[0]=='q')/* quit */
  1415.       break;
  1416.     if(tmpBuf[0]=='\0')/* null line */
  1417.       goto next;
  1418.     if(tmpBuf[0]=='#')  /* comment line */
  1419.       goto next;
  1420.     i = strlen(tmpBuf);
  1421.     if(tmpBuf[i-1]==':'){ /* label */
  1422.       /* process label */
  1423.       tmpBuf[i-1]='\0';
  1424.       if(i=islocal(tmpBuf)){
  1425.         local_label[i&0xff]=PC;
  1426.         solve_local(i&0xff);
  1427.       }
  1428.       else if(regist_label(tmpBuf,PC)<0)
  1429.         fprintf(stderr,"%d: label error!\n",linenum);
  1430.       scan_sym(tmpBuf);
  1431.       if(tmpBuf[0]=='\0')
  1432.         goto next;
  1433.     }
  1434.     PC = asmcpu(PC,tmpBuf);
  1435.   next:
  1436.     printf("%08x ",PC);fflush(stdout);
  1437.   }
  1438.   solve_label();
  1439. }
  1440.